package com.ruoyi.file.task;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.ZipUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.file.domain.FilePublishDto;
import com.ruoyi.file.domain.TblFile;
import com.ruoyi.file.domain.TblFileData;
import com.ruoyi.file.service.IModelTaskLayersService;
import com.ruoyi.file.service.IModelTaskProcesssService;
import com.ruoyi.file.service.ITblFileDataService;
import com.ruoyi.file.service.ITblFileService;
import com.ruoyi.framework.gis.FileConfig;
import com.ruoyi.framework.gis.GeoserverConfig;
import com.ruoyi.framework.minio.MinioService;
import com.ruoyi.framework.task.AbstractTask;
import com.ruoyi.framework.task.TaskResult;
import com.ruoyi.gis.geoserver.domain.GeoServerLayer;
import com.ruoyi.gis.geoserver.service.GeoserverService;
import com.ruoyi.gis.domain.GeoLayer;
import com.ruoyi.gis.domain.GisLayer;
import com.ruoyi.gis.service.IGisLayerService;
import com.ruoyi.gis.utils.GeoUtils;
import com.ruoyi.file.domain.ModelTaskLayers;
import com.ruoyi.file.domain.ModelTaskProcesss;
import it.geosolutions.geoserver.rest.GeoServerRESTPublisher;
import org.apache.commons.io.IOUtils;
import org.geotools.coverage.Category;
import org.geotools.coverage.GridSampleDimension;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridEnvelope2D;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.coverage.grid.io.GridFormatFinder;
import org.geotools.data.FeatureSource;
import org.geotools.data.Query;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.gce.geotiff.GeoTiffFormat;
import org.geotools.gce.image.WorldImageFormat;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.CRS;
import org.geotools.referencing.NamedIdentifier;
import org.geotools.referencing.operation.matrix.XAffineTransform;
import org.geotools.util.NumberRange;
import org.geotools.util.factory.Hints;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.GeometryType;
import org.opengis.geometry.DirectPosition;
import org.opengis.geometry.Envelope;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.crs.SingleCRS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import java.awt.geom.AffineTransform;
import java.awt.image.ColorModel;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.stream.Collectors;

public class PublishLayerTask extends AbstractTask {
    private final Logger logger = LoggerFactory.getLogger(PublishLayerTask.class);
    private GeoserverConfig geoserverConfig;
    private FilePublishDto filePublishDto;
    private ITblFileService tblFileService;
    private IGisLayerService gisLayerService;
    private IModelTaskProcesssService modelTaskProcessService;
    private IModelTaskLayersService modelTaskLayerService;
    private MinioService minioService;
    private GeoserverService geoserverService;
    private RuoYiConfig ruoYiConfig;
    private FileConfig fileConfig;
    private ITblFileDataService tblFileDataService;

    public PublishLayerTask(FilePublishDto filePublishDto) {
        this.filePublishDto = filePublishDto;
    }

    @Override
    public TaskResult call() {
        TaskResult result = new TaskResult();
        tblFileDataService = SpringUtils.getBean(ITblFileDataService.class);
        modelTaskProcessService=SpringUtils.getBean(IModelTaskProcesssService.class);
        modelTaskLayerService=SpringUtils.getBean(IModelTaskLayersService.class);
        ruoYiConfig = SpringUtils.getBean(RuoYiConfig.class);
        fileConfig = SpringUtils.getBean(FileConfig.class);
        geoserverConfig = SpringUtils.getBean(GeoserverConfig.class);
        tblFileService = SpringUtils.getBean(ITblFileService.class);
        gisLayerService = SpringUtils.getBean(IGisLayerService.class);
        minioService = SpringUtils.getBean(MinioService.class);
        geoserverService = SpringUtils.getBean(GeoserverService.class);
        TblFile tblFile = tblFileService.selectTblFileById(filePublishDto.getPublishFileId());

        if(tblFile==null){
            logger.info("db file info is error......................");
            return result;
        }
        try {
            String taskId=filePublishDto.getTaskId();
            logger.info("filePublishDto TaskId{}......................",taskId);
            if(taskId!=null){
                tblFile.setTaskId(taskId);
                logger.info("db file info publishlayer taskId {}...................",taskId);
            }
            if(FileUtils.isTifFile(tblFile.getFileName())){
                logger.info("db file info publishTif......................");

                publishTif(tblFile);
            }else if(FileUtils.isShpFile(tblFile.getFileName())){
                ///opt/geoserver/data_dir/shp/1782602952459497472.zip
                ///opt/geoserver/data_dir/shp/1782602952459497472.zip
                logger.info("db file info publishShp......................");
                publishShp(tblFile);
            }
        } catch (Exception e) {
            logger.info("db file info PublishLayerTask error......................");
            logger.error("PublishLayerTask",e);
        }
        return result;
    }
    private void publishTif(TblFile tblFile) throws Exception {

        //本地是否有
        File bucketFolder = new File(fileConfig.getMinioLocalDir(),tblFile.getBucket());
        File objectFile =  new File(bucketFolder,tblFile.getObjectName());
        if(!objectFile.exists()){
            if(!bucketFolder.exists()){
                bucketFolder.mkdirs();
            }
            logger.info("db file info not exist in load dist will download from minio......................");
            //下载到本地
            ResponseEntity<StreamingResponseBody> download = minioService.download1(tblFile.getBucket(), tblFile.getObjectName());
            logger.info("download 1.................");
            FileUtils.createParentDirectories(objectFile);
            StreamingResponseBody responseBody = download.getBody();
            logger.info("download 2.................");
            try (FileOutputStream fileOutputStream = new FileOutputStream(objectFile)) {
                // 将 StreamingResponseBody 写入到 FileOutputStream
                responseBody.writeTo(fileOutputStream);
                logger.info("download 2.................");
            } catch (IOException e) {
                logger.error("Error writing file", e);
            }
//
//                ResponseEntity<byte[]> download = minioService.download(tblFile.getBucket(), tblFile.getObjectName());
//            logger.info("download 1.................");
//            FileUtils.createParentDirectories(objectFile);
//            logger.info("download 2.................");
////            FileUtils.writeByteArrayToFile(objectFile,download.getBody());
//            try (ByteArrayInputStream inputStream = new ByteArrayInputStream(download.getBody());
//                 FileOutputStream fileOutputStream = new FileOutputStream(objectFile)) {
//                // 将数据从 InputStream 写入到 OutputStream
//                IOUtils.copy(inputStream, fileOutputStream);
//            }
//             catch(Exception e){
//                logger.error("Error writing file", e);
//            }
            logger.info("download 3.................");
        }
        File geoserverRootFolder = new File(geoserverConfig.getGeoserverHostDataDirRoot(),"tif");
        logger.info("geoserverRootFolder.................");
        File geoserverDockerRootFolder = new File(geoserverConfig.getGeoserverDataDir(),"tif");
        File tifFileFolder = new File(geoserverRootFolder,tblFile.getId()+"");
        File tifFileDockerFolder = new File(geoserverDockerRootFolder,tblFile.getId()+"");
        File tifFile = new File(tifFileFolder,tblFile.getFileName());
        File tifFileDocker = new File(tifFileDockerFolder,tblFile.getFileName());
        if(tifFile.exists()){
            tifFile.delete();
        }else {
            tifFileFolder.mkdirs();
        }
        tifFile.createNewFile();
        logger.info("db file info copy file to geoserver dir......................");
        FileUtils.copyFile(objectFile,tifFile);
        JSONObject tifInfo = new JSONObject();
        tifInfo.put("fileName",tifFile.getName());
        String layerName = tblFile.getId()+"";
        String layerTitle = FileUtils.getNameNotSuffix(tblFile.getFileName());
        GisLayer parentGislayer = "0".equals(filePublishDto.getParentLayerId())?null:gisLayerService.
                selectGisLayerByLayerId(filePublishDto.getParentLayerId());
        String workspace = (parentGislayer!=null?parentGislayer.getLayerId():tblFile.getId())+"";
//        String crs = GeoUtils.readTiffCrs(tifFile.getPath());;//GeoServerRESTPublisher.DEFAULT_CRS;
//        tifInfo.put("crs",crs.toString());
        AbstractGridFormat format = GridFormatFinder.findFormat(tifFile);
        // this is a bit hacky but does make more geotiffs work
        Hints hints = new Hints();
        if (format instanceof GeoTiffFormat) {
            hints = new Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);
        }
        AbstractGridCoverage2DReader reader = null;
        GridCoverage2D cov = null;
        if (format instanceof GeoTiffFormat) {
            hints = new Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);
//            reader = format.getReader(tifFile, hints);
//            cov = reader.read(null);
        }else if(format instanceof WorldImageFormat){
//            reader = new WorldImageReader(tifFile,hints);
//            cov = reader.read(null);
        }
        reader = format.getReader(tifFile, hints);
        cov = reader.read(null);
        Envelope envelope = cov.getEnvelope();
        CoordinateReferenceSystem crs = cov.getCoordinateReferenceSystem();
        SingleCRS horizontalCRS = CRS.getHorizontalCRS(crs);
        if(horizontalCRS==null){
            horizontalCRS = CRS.getVerticalCRS(crs);
        }
        String crsStr = GeoServerRESTPublisher.DEFAULT_CRS;
//        if(horizontalCRS!=null&&horizontalCRS.getIdentifiers()!=null
//                &&horizontalCRS.getIdentifiers().size()>0){
//            Object o = horizontalCRS.getIdentifiers().toArray()[0];
//            crsStr = ((NamedIdentifier) o).toString();
//        }
        tifInfo.put("crsStr",crsStr);
        tifInfo.put("crs",crs.toString());
        DirectPosition lowerCorner = envelope.getLowerCorner();
        double[] westSouth = lowerCorner.getCoordinate();
        DirectPosition upperCorner = envelope.getUpperCorner();
        double[] eastNorth = upperCorner.getCoordinate();
        GridGeometry2D gridGeometry = cov.getGridGeometry();
        GridEnvelope2D gridRange = gridGeometry.getGridRange2D();
        int height = gridRange.height;
        int width = gridRange.width;
        tifInfo.put("width",width);
        tifInfo.put("height",height);
        AffineTransform gridToCRS = (AffineTransform) gridGeometry.getGridToCRS();
        double xRes = XAffineTransform.getScaleX0(gridToCRS);
        double yRes = XAffineTransform.getScaleY0(gridToCRS);
        tifInfo.put("xRes",xRes);
        tifInfo.put("yRes",yRes);
        //起始点
        double translateX = gridToCRS.getTranslateX();
        double translateY = gridToCRS.getTranslateY();
        tifInfo.put("translateX",translateX);
        tifInfo.put("translateY",translateY);
//        envelopeParams.put(NORTH, eastNorth[1]);
//        envelopeParams.put(SOUTH, westSouth[1]);
//        envelopeParams.put(WEST, westSouth[0]);
//        envelopeParams.put(EAST, eastNorth[0]);
//        envelopeParams.put(XRES, xRes);
//        envelopeParams.put(YRES, yRes);
//        envelopeParams.put(ROWS, (double) height);
//        envelopeParams.put(COLS, (double) width);
        JSONObject bound = new JSONObject();
        bound.put("maxX",eastNorth[0]);//EAST 东
        bound.put("maxY",eastNorth[1]);//NORTH 北
        bound.put("minX",westSouth[0]);//WEST  西
        bound.put("minY",westSouth[1]);//SOUTH 南
        tifInfo.put("bbox",bound);
        int numBands = cov.getNumSampleDimensions();
        tifInfo.put("numBands",numBands);
        JSONArray bands = new JSONArray();
        for (int i = 0; i < numBands; i++) {
            JSONObject band = new JSONObject();
            GridSampleDimension dim = cov.getSampleDimension(i);
            double[] noDataValues = dim.getNoDataValues();
            double maximumValue = dim.getMaximumValue();
            double minimumValue = dim.getMinimumValue();
            ColorModel colorModel = dim.getColorModel();
            band.put("noDataValues",noDataValues!=null&&noDataValues.length>0?noDataValues[0]:null);
            band.put("maximumValue",maximumValue);
            band.put("minimumValue",minimumValue);
            if(colorModel!=null){
                int pixelSize = colorModel.getPixelSize();
                band.put("pixelSize",pixelSize);
            }
            band.put("description",dim.getDescription()!=null?dim.getDescription().toString():"");
//            band.put("");
            JSONArray cates = new JSONArray();
            List<Category> categories = dim.getCategories();
            if(categories!=null){
                for(Category category:categories) {
                    JSONObject cate = new JSONObject();
                    cate.put("name",category.getName()!=null?category.getName().toString():"");
                    NumberRange<? extends Number> range = category.getRange();
                    if(range!=null){
                        double maximum = range.getMaximum();
                        double minimum = range.getMinimum();
                        cate.put("maximum",maximum);
                        cate.put("minimum",minimum);
                    }
//                    Category.NODATA.getName().equals(category.getName())
                    cates.add(cate);
                }
            }
            band.put("categories",cates);
            //这里依次输出 RED_BAND  GREEN_BANK BLUE_BANK
            System.out.println(dim.getDescription().toString());
            bands.add(band);
        }
        tifInfo.put("bands",bands);
        reader.dispose();
        cov = null;
        reader = null;
        format = null;
        //如果shp、压缩包以及publishShp的参数layerName名称不一致，会发布失败 https://www.cnblogs.com/Jeely/p/14767996.html
        logger.info("publish geotif start crs............................................."+crs);
//        String destTifPath = tifFile.getCanonicalPath().
//                replace(geoserverConfig.getGeoserverHostDataDirRoot(),
//                geoserverConfig.getGeoserverDataDir());
//        tifFile = null;
//        File destFile = new File(destTifPath);
        tifFile = null;
        String storeName = tblFile.getId()+"";
        boolean result = geoserverService.publishExternalGeoTIFF(tifFileDocker,//tifFile,
                workspace, storeName,
                layerName, layerTitle, crsStr);
//        boolean result = geoserverService.publishGeoTIFF(tifFileDocker,//tifFile,
//                workspace, storeName,
//                layerName, crsStr);
        logger.info("publish geotif end workspace {} layerName {} layerTitle {} result {} ",
                workspace,layerName,layerTitle,result);
        if(!result){
            logger.error("publish tif layer error .......");
            return;
        }
        //获取图层信息
        GisLayer gisLayer = savePublishInfo(workspace,storeName, layerName, layerTitle, tblFile, parentGislayer);
        logger.info("layerId is {} ", gisLayer.getLayerId());
        if(gisLayer!=null){
            //保存gislayer 和文件关联
            tblFile.setLayerId(gisLayer.getLayerId());
            tblFile.setPublished(true);
            if(tifInfo!=null){
                tblFile.setFileInfo(JSON.toJSONString(tifInfo));
            }
//        if(shpInfo!=null)tblFile.setFileInfo(JSON.toJSONString(shpInfo));
            tblFileService.updateTblFile(tblFile);
            //添加图层任务关联
            logger.info("taskId is {} ", tblFile.getTaskId());
            ModelTaskProcesss currMTP=modelTaskProcessService.selectModelTaskProcessById(Long.parseLong(tblFile.getTaskId()));
            logger.info("ModelTaskProcess is {},{} ", currMTP.getPublishLayerLabel(),currMTP.getPublicLayerType());
            if(currMTP!=null){
                ModelTaskLayers insertTaskLayer=new ModelTaskLayers();
                insertTaskLayer.setFileId(gisLayer.getFileId());
                insertTaskLayer.setTaskId(Long.parseLong(tblFile.getTaskId()));
                insertTaskLayer.setLayerId(gisLayer.getLayerId());
                insertTaskLayer.setTaskLayerName(currMTP.getPublishLayerLabel());
                insertTaskLayer.setTaskType(currMTP.getPublicLayerType());
                //新增关联表
               int insertC= modelTaskLayerService.insertModelTaskLayer(insertTaskLayer);
               logger.info("insert layer and task is {}", insertC);
            }
        }
    }
    private void publishShp(TblFile tblFile) throws IOException {
        TblFile query = new TblFile();
        query.setPid(tblFile.getPid());
        //query.setGroup(tblFile.getGroup());
        List<TblFile> tblFiles = tblFileService.selectTblFileList(query);
        if(tblFiles==null)return;
        File bucketFolder = new File(fileConfig.getMinioLocalDir(),tblFile.getBucket());
        logger.info("publish shp  download shp files start  file size {}................................",tblFiles.size());
        File geoserverRootFolder = new File(geoserverConfig.getGeoserverHostDataDirRoot(),"shp");
        File geoserverDockerRootFolder = new File(geoserverConfig.getGeoserverDataDir(),"shp");
        File shpZipFolder = new File(geoserverRootFolder,tblFile.getId()+"");
        File shpZipDockerFolder = new File(geoserverDockerRootFolder,tblFile.getId()+"");
        File zipShpFile = new File(geoserverRootFolder,tblFile.getId()+".zip");
        File zipShpDockerFile = new File(geoserverDockerRootFolder,tblFile.getId()+".zip");
        if(!shpZipFolder.exists()){
            shpZipFolder.mkdirs();
        }
        for (TblFile item: tblFiles) {
            File objectFile =  new File(bucketFolder,item.getObjectName());
            if(!objectFile.exists()){
                logger.info("db file info not exist in load dist will download from minio......................");
                //下载到本地
                ResponseEntity<byte[]> download = minioService.download(item.getBucket(), item.getObjectName());
                FileUtils.createParentDirectories(objectFile);
                FileUtils.writeByteArrayToFile(objectFile,download.getBody());
            }
            String ext = FileUtils.getExt(item.getFileName());
            //shp重新命名,用shp文件的id作所有shp相关的文件名
            File destFile = new File(shpZipFolder,tblFile.getId()+"."+ext);
            FileUtils.copyFile(objectFile,destFile);
        }
        File shpFile = new File(bucketFolder,tblFile.getObjectName());
        logger.info("publish shp  download shp files ok.............................................");
        //压缩
        logger.info("publish shp  start zip  src: {}  zip: .............................................",
                shpZipFolder.getCanonicalPath(),
                zipShpFile.getCanonicalPath());
        ZipUtils.zip(shpZipFolder.getCanonicalPath(),
                zipShpFile.getCanonicalPath(),false);
        //压缩完成之后删除压缩目录
        FileUtils.deleteDirectory(shpZipFolder);
        logger.info("publish shp  end zip.............................................");
        String storeName = tblFile.getId()+"";
        String layerName = tblFile.getId()+"";
        String layerTitle = FileUtils.getNameNotSuffix(tblFile.getFileName());
        GisLayer parentGislayer = "0".equals(filePublishDto.getParentLayerId())?null:gisLayerService.
                selectGisLayerByLayerId(filePublishDto.getParentLayerId());
        String workspace = (parentGislayer!=null?parentGislayer.getLayerId():tblFile.getId())+"";
        //String crs = GeoServerRESTPublisher.DEFAULT_CRS;
//        String crs = GeoUtils.getShpCrs(shpFile.getPath());
//        JSONObject shpInfo = GeoUtils.readShpFile(shpFile.getPath());
        JSONObject shpInfo = new JSONObject();
        shpInfo.put("fileName",shpFile.getName());
        //文件编码：dbf文件的第29字节是编码信息，另外cpg文件就是编码明文
        Charset charset = GeoUtils.getCharsetByCpg(shpFile.getParent(),
                FileUtils.getNameNotSuffix(shpFile.getName()));
        if(charset==null){
            File dbfFile = new File(shpFile.getParent(),
                    FileUtils.getNameNotSuffix(shpFile.getName())+".dbf");
            charset = GeoUtils.getCharsetByDbf(dbfFile);
            dbfFile = null;
        }
        shpInfo.put("charset",charset.toString());
        ShapefileDataStore shapefileDataStore = new ShapefileDataStore(shpFile.toURI().toURL());
        // 设置编码,防止属性的中文字符出现乱码
        shapefileDataStore.setCharset(charset);//(Charset.forName("GBK"));//(Charset.forName("UTF-8"));//(charset);//
        // 这个typeNamae不传递，默认是文件名称
        //org/geotools/factory/Hints  把gt-main依赖去掉，他们会自动依赖
        FeatureSource featuresource = shapefileDataStore.
                getFeatureSource(shapefileDataStore.getTypeNames()[0]);
        // 读取投影
        CoordinateReferenceSystem crs = featuresource.getSchema()
                .getCoordinateReferenceSystem();

        shpInfo.put("crs",crs.toString());
        SingleCRS horizontalCRS = CRS.getHorizontalCRS(crs);
        if(horizontalCRS==null){
            horizontalCRS = CRS.getVerticalCRS(crs);
        }
        String crsStr = GeoServerRESTPublisher.DEFAULT_CRS;
        if(horizontalCRS!=null&&horizontalCRS.getIdentifiers()!=null
                &&horizontalCRS.getIdentifiers().size()>0){
            Object o = horizontalCRS.getIdentifiers().toArray()[0];
            crsStr = ((NamedIdentifier) o).toString();
        }
        shpInfo.put("crsStr",crsStr);
//        String destTifPath = zipShpFile.getCanonicalPath().
//                replace(geoserverConfig.getGeoserverHostDataDirRoot(),
//                        geoserverConfig.getGeoserverDataDir());
//        zipShpFile = null;
//        File destFile = new File(destTifPath);
        geoserverService.publishShpData(zipShpDockerFile,//zipShpFile,
                workspace,
                storeName,layerName, crsStr);
        GisLayer gisLayer = savePublishInfo(workspace, storeName,layerName, layerTitle, tblFile, parentGislayer);
        if(gisLayer==null){
            logger.info("publish shp error .............................................");
            return;
        }
        logger.info("publish shp update vactor formate  {}......................",GisLayer.format_mapbox_vector);
        gisLayer.setSourceFormat(GisLayer.format_mapbox_vector);
        gisLayerService.updateGisLayer(gisLayer);
//        String sourceFormat = "application/vnd.mapbox-vector-tile";
        geoserverService.updateLayerTitleCache(gisLayer.getWorkspace(),
                gisLayer.getLayerName(), gisLayer.getSourceFormat());
        logger.info("get shp file crs info ............"+crsStr);
        //如果shp、压缩包以及publishShp的参数layerName名称不一致，会发布失败 https://www.cnblogs.com/Jeely/p/14767996.html
        logger.info("publish shp start .............................................");
        logger.info("get shp other info .........................................");
        shpInfo.put("typeNames",shapefileDataStore.getTypeNames());
        // 读取bbox
        ReferencedEnvelope bbox  = featuresource.getBounds();
        JSONObject bound = new JSONObject();
        bound.put("maxX",bbox.getMaxX());
        bound.put("maxY",bbox.getMaxY());
        bound.put("minX",bbox.getMinX());
        bound.put("minY",bbox.getMinY());
        shpInfo.put("bbox",bound);
        // 特征总数
        int count = featuresource.getCount(Query.ALL);
        shpInfo.put("featureSourceCount",count);
        // 获取当前数据的geometry类型（点、线、面）
        GeometryType geometryType = featuresource.getSchema().getGeometryDescriptor().getType();
        shpInfo.put("geometryType",geometryType.getName().toString());
        // 读取要素
        SimpleFeatureCollection simpleFeatureCollection = (SimpleFeatureCollection) featuresource.
                getFeatures();
        // 获取当前矢量数据有哪些属性字段值
        List<AttributeDescriptor> attributes = simpleFeatureCollection.
                getSchema().getAttributeDescriptors();
        List<JSONObject> types = attributes.stream().map(item -> {
            JSONObject filed = new JSONObject();
            filed.put("type", item.getType().getBinding().getSimpleName());
            filed.put("localName", item.getName().toString());
            filed.put("defaultValue", item.getDefaultValue());
            return filed;
        }).collect(Collectors.toList());
        shpInfo.put("attributes",types);
        logger.info("get shp info end will db.........................................");
        //org.locationtech.jts.geom 冲突
        //保存gislayer 和文件关联
        tblFile.setLayerId(gisLayer.getLayerId());
        tblFile.setPublished(true);
        if(shpInfo!=null){
            tblFile.setFileInfo(JSON.toJSONString(shpInfo));
        }
        tblFileService.updateTblFile(tblFile);
        logger.info("get shp data info save into db ok.........................................");
        // 拿到迭代器
        SimpleFeatureIterator simpleFeatureIterator = simpleFeatureCollection.features();
//        JSONArray attValues = new JSONArray();
        // 遍历每一个要素
        logger.info("get shp data info save into db.........................................");
//        JSONObject fieldsValues = new JSONObject();
        while(simpleFeatureIterator.hasNext()) {
            JSONObject itemVal = new JSONObject();//防止不停的
            SimpleFeature simpleFeature = simpleFeatureIterator.next();
            // java8新特性流api
            attributes.stream().forEach((a) -> {
                // 依次读取这个shape中每一个属性值，当然这个属性值，可以处理其它业务
//                    System.out.println(a.getLocalName() + ":" + simpleFeature.getAttribute(a.getLocalName()));
//                if(!"the_geom".equals(a.getLocalName())){
//                    String val = simpleFeature.getAttribute(a.getLocalName()).toString();
//                    if(!StringUtils.isEmpty(val)){
//                        if(fieldsValues.get(a.getLocalName())!=null){
//                            HashSet<String> values = (HashSet<String>) fieldsValues.get(a.getLocalName());
//                            values.add(val);
//                        }else {
//                            HashSet<String> values = new HashSet<>();
//                            values.add(val);
//                            fieldsValues.put(a.getLocalName(),values);
//                        }
//                    }
//                }
                itemVal.put(a.getLocalName(),simpleFeature.
                        getAttribute(a.getLocalName()).toString());

            });
//            attValues.add(itemVal);
            TblFileData fileData = new TblFileData();
            fileData.setFileId(tblFile.getId());
            fileData.setFileInfo(JSON.toJSONString(itemVal));
            //tblFileDataService.insertTblFileData(fileData);
        }
//        shpInfo.put("data",attValues);
        shapefileDataStore.dispose();
        logger.info("publish shp end .............................................");
    }
    private GisLayer savePublishInfo(String workspace,String store,String layerName,
                                     String layerTitle,
                                     TblFile tblFile,
                                     GisLayer parentGislayer) throws IOException {
        String wsAndLayer = workspace+":"+layerName;
        logger.info("publish layer ok savePublishInfo  will   getLayerConfig .......");
        GeoServerLayer layerConfig = geoserverService.getLayerConfig(wsAndLayer);
        if (layerConfig != null) {
            logger.info("publish layer  getLayer info .......");
            GeoLayer layer = geoserverService.getLayer(workspace,layerName);
            if (layer != null) {
                GisLayer query = gisLayerService.selectGisLayerByFileId(tblFile.getId());
                GisLayer subLayer = new GisLayer();
                if(query!=null){
                    subLayer.setLayerId(query.getLayerId());
                }else {
                    subLayer.setLayerId(IdUtil.getSnowflakeNextId());
                }
                subLayer.setUserId(tblFile.getUserId());
                subLayer.setBzid(layerConfig.getId());
                subLayer.setSourceUrl(layer.getSourceUrl());
                subLayer.setLayerTitle(layerTitle);//(StringUtils.isEmpty(layer.getTitle()) ? layerTitle : layer.getTitle());
                subLayer.setLayerStyle(layer.getStyle());
                subLayer.setEndpoint(geoserverConfig.getEndpoint());
                subLayer.setLayerName(layer.getName());
                subLayer.setGroup(GisLayer.type_layer);//图层
                subLayer.setParentId(parentGislayer!=null?parentGislayer.getLayerId():0L);
                subLayer.setAncestors(parentGislayer!=null?
                        parentGislayer.getAncestors() + subLayer.getLayerId() + ",":"0,"+ subLayer.getLayerId() + ",");
                subLayer.setFileId(tblFile.getId());
                subLayer.setWorkspace(workspace);
                subLayer.setStoreType(layer.getStoreType());
                subLayer.setStore(store);///layer.getStoreName());//这个getStoreName 带有工作空间
                subLayer.setStatus("1");
                subLayer.setCrs(layer.getCrs());
                subLayer.setDelFlag("0");
                subLayer.setSourceType(layer.getType());
                subLayer.setLayerType(layer.getType());
                subLayer.setModel(GisLayer.model_file);
                String bounds = JSON.toJSONString(layer.getBoundary());
                subLayer.setBoundary(bounds);
                String[] mimeFormats = layerConfig.getMimeFormats();
                subLayer.setSourceFormat(mimeFormats != null ? mimeFormats[0] : null);

                if(query!=null){
                    gisLayerService.updateGisLayer(subLayer);
                }else {
                    gisLayerService.insertGisLayer(subLayer);
                }
                if(parentGislayer!=null){
                    gisLayerService.updateParentBoundary(parentGislayer.getLayerId());
                }
                logger.info(" publish and save info ok  layer  {}  success  bounds {} .......",layer.getName(),bounds);

                return subLayer;
            }else {
                logger.info("publish layer  get layer info  null publish error .......");
            }
        }else {
            logger.info("publish layer  getLayerConfig null publish error .......");
        }
        return null;
    }
}
